package network;
import java.net.*;
import java.security.NoSuchAlgorithmException;
import java.io.*;

import encryption.RSA;
import entities.User;

import authentication.ClientAuthentication;

import registration.ClientRegistration;
import voting.ClientVoting;

public class Client
{
	public static Client client = null;
	Socket socket;
	private String randomPassword;
	public Client(){

	}
	/**
	 * Connect to the server using the default parameters
	 * @return true in case connection succeeded 
	 */
	public boolean connect(){
		return connect("127.0.0.1" , 8000);
	}

	/** 
	 *  Connect to the server using the IP and Port arguments
	 * @param IP
	 * @param port
	 * @return true in case connection succeeded
	 */
	public boolean connect(String IP , int port){
		try {
			socket = new Socket(IP,port);
			return true;
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * Send to the server message
	 * @param message
	 * @return true if message is sent
	 */
	public boolean sendMessage(String message)	{
		if(socket.isClosed())
		{
			return false;
		}
		DataOutputStream outToServer;
		try {
			outToServer = new DataOutputStream(socket.getOutputStream());
			outToServer.writeBytes(message+"\n");
		} catch (IOException e) {
			try {
				socket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
			return false;
		}
		return true;
	}
	/**
	 * Receives an RSA as an array of bytes
	 * @return
	 */
	public byte[] receiveRSAMessage(){
		if(socket.isClosed())
		{
			return null;
		}
		DataInputStream inFromServer;
		byte[]  inMessage = new byte[256];
		try {
			inFromServer =new DataInputStream(socket.getInputStream());
			inFromServer.read(inMessage, 0, 256);
		} catch (IOException e) {
			try {
				socket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
		return inMessage;

	}
	
	/**
	 * Receive message from server
	 * @return message received
	 */
	public String receiveMessage()
	{
		if(socket.isClosed())
		{
			return null;
		}
		BufferedReader inFromServer;
		String inMessage = null;
		try {
			inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			inMessage= inFromServer.readLine();
		} catch (IOException e) {
			try {
				socket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
		return inMessage;

	}

	/** 
	 * Sends an RSA message
	 * @param message
	 * @return
	 */
	public boolean sendRSAMessage(byte[] message)	{
		if(socket.isClosed())
		{
			return false;
		}
		DataOutputStream outToServer;
		try {
			outToServer = new DataOutputStream(socket.getOutputStream());
			outToServer.write(message);
		} catch (IOException e) {
			try {
				socket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static void initializeClient(){ 
		client = new Client();
		client.connect();
	}

	public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
		client = new Client();
		client.connect();
		

		RSA rsa=new RSA();
	    
		
		byte[]s = rsa.rsaEncryptToBytes("sdsfsd" , "20933460749432575217334381777058471331301493740374616705148769499805250963247808290685090402617548284135775594628275659638677185581251302510135025928441179272839574620827721132069021233071821355572378366192461219436764318678652837174798617260920569130559861071080236014771218948146560709489003058133737564710113119690796009796491833075775450813102849152135514564440276664640401918591454988637327897533078188241042687677594249848775767520517131919594651846169535352102651682871981963072682344980077032214435239799418195563595995226474078153014757286078987648908955125278827944385334589478822652160627442975709310329633" , "65537");
		client.sendRSAMessage(s);
		//System.out.println(rsa.rsadecrypt( s, "20933460749432575217334381777058471331301493740374616705148769499805250963247808290685090402617548284135775594628275659638677185581251302510135025928441179272839574620827721132069021233071821355572378366192461219436764318678652837174798617260920569130559861071080236014771218948146560709489003058133737564710113119690796009796491833075775450813102849152135514564440276664640401918591454988637327897533078188241042687677594249848775767520517131919594651846169535352102651682871981963072682344980077032214435239799418195563595995226474078153014757286078987648908955125278827944385334589478822652160627442975709310329633" , "3620881502900158271872416372808258403827360621341938980569242581286789522245100550577630724690976507148071351155929213690953882169599840780854946883818441616749460883191220940127476459070481817702496012316061772487833747601220815145849171083049202308070656043178136861062400445491698005748925624715871172521637029435918105522585822533307996418488232941216486704573943546705578345774679089554754867397781298204874096754679579069422260050314154430715038700407333328748191646495057696927472254656081214635750896257992538180755910070777047131546348663781780030623572332244737889835280297494466090995605241656072761386497"));
		

		CAClient c = new CAClient();
		c.CAClientFlow();
		
	//	System.out.println(ClientVoting.calculateSum(1, 6));		

	}
	public void setRandomPassword(String randomPassword) {
		this.randomPassword = randomPassword;
	}
	public String getRandomPassword() {
		return randomPassword;
	}
}